package de.haw.avl.visualization;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;

import javax.swing.JApplet;
import javax.swing.JFrame;

import org.apache.commons.collections15.Factory;
import org.apache.commons.collections15.functors.ConstantTransformer;

import de.haw.avl.AvlTree;
import de.haw.avl.Node;
import edu.uci.ics.jung.algorithms.layout.TreeLayout;
import edu.uci.ics.jung.graph.DelegateTree;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.EdgeShape;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.DefaultVertexLabelRenderer;
import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;

public class TreeVisualization extends JApplet {
	private static final long serialVersionUID = 5477157009597668273L;

	private final DelegateTree<String, Integer> graph;

	private final TreeLayout<String, Integer> treeLayout;

	private final VisualizationViewer<String, Integer> vv;

	private final Factory<Integer> edgeFactory = new Factory<Integer>() {
		int i = 0;

		@Override
		public Integer create() {
			return i--;
		}
	};

	private TreeVisualization(AvlTree tree) {
		graph = new DelegateTree<String, Integer>();

		graph.setRoot(tree.getRoot().toString());
		fillGraph(tree.getRoot(), null);

		treeLayout = new TreeLayout<String, Integer>(graph);
		vv = new VisualizationViewer<String, Integer>(treeLayout,
				new Dimension(800, 600));
		vv.setBackground(Color.white);
		vv.setPreferredSize(new Dimension(800, 600));
		vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line());
		vv.getRenderContext().setVertexLabelTransformer(
				new ToStringLabeller<String>());
		// // add a listener for ToolTips
		vv.setVertexToolTipTransformer(new ToStringLabeller<String>());
		// vv.getRenderContext().setArrowFillPaintTransformer(
		// new ConstantTransformer(Color.lightGray));
		vv.getRenderContext().setVertexLabelRenderer(
				new DefaultVertexLabelRenderer(Color.green));
		vv.getRenderContext().setEdgeDrawPaintTransformer(
				new ConstantTransformer(Color.white));
		vv.getRenderContext().setEdgeStrokeTransformer(
				new ConstantTransformer(new BasicStroke(2.5f)));

		// vv.getRenderContext().setVertexFillPaintTransformer(
		// new VertexPaintTransformer(vv.getPickedVertexState()));

		DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();
		graphMouse
				.setMode(edu.uci.ics.jung.visualization.control.ModalGraphMouse.Mode.PICKING);
		vv.setGraphMouse(graphMouse);

		vv.setBackground(Color.gray);
		// vv.getRenderContext().setVertexLabelTransformer(
		// new ToStringLabeller<Integer>());
		vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);

		Container content = getContentPane();
		final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
		content.add(panel);
	}

	int i = 0;

	private void fillGraph(Node node, Node prev) {
		if (node != null) {
			if (prev != null) {
				graph.addEdge(edgeFactory.create(), prev.toString(),
						node.toString());
			}
			fillGraph(node.getLeftHand(), node);
			fillGraph(node.getRightHand(), node);
		}
	}

	public static void showTree(AvlTree tree) {
		JFrame frame = new JFrame();
		Container content = frame.getContentPane();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		TreeVisualization visu = new TreeVisualization(tree);
		System.out.println("Knoten:" + visu.getVertices());

		content.add(visu);
		frame.pack();
		frame.setVisible(true);
	}

	private int getVertices() {
		return graph.getVertexCount();
	}

}
